package com.seeyon.ctp.portal.section;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import com.seeyon.apps.nygj.manager.CustomThirdPendingManager;
import com.seeyon.apps.nygj.util.StrKit;
import com.seeyon.ctp.common.formula.FormulaUtil;
import com.seeyon.ctp.portal.section.templete.PortletPackageTemplete;
import com.seeyon.ctp.util.concurrent.ExecutorServiceFactory;
import org.apache.commons.collections.CollectionUtils;

import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.seeyon.apps.cip.constants.CIPConstants;
import com.seeyon.apps.cip.manager.RegisterManager;
import com.seeyon.apps.cip.manager.ThirdPendingManager;
import com.seeyon.apps.cip.manager.ThirdpartyPendingPullManager;
import com.seeyon.apps.cip.messageandpending.manager.MessageOrPendingCacheManager;
import com.seeyon.apps.cip.po.RegisterPO;
import com.seeyon.apps.cip.po.ThirdPendingPO;
import com.seeyon.apps.cip.util.CIPUtil;
import com.seeyon.apps.m3.pending.utils.M3PendingUtils;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.SystemEnvironment;
import com.seeyon.ctp.common.authenticate.domain.User;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.common.i18n.ResourceUtil;
import com.seeyon.ctp.organization.manager.OrgManager;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;

import com.seeyon.ctp.portal.section.templete.BaseSectionTemplete;
import com.seeyon.ctp.portal.section.templete.MultiRowVariableColumnTemplete;
import com.seeyon.ctp.portal.section.templete.MultiRowVariableColumnTemplete.Cell;
import com.seeyon.ctp.portal.section.templete.mobile.MListTemplete;
import com.seeyon.ctp.portal.section.util.SectionUtils;
import com.seeyon.ctp.util.Datetimes;
import com.seeyon.ctp.util.FlipInfo;
import com.seeyon.ctp.util.Strings;
import com.seeyon.ctp.portal.util.PortletPropertyContants.PropertyName;

public class ThirdPendingSection extends BaseSectionImpl {


    private static final Log log = LogFactory.getLog(ThirdPendingSection.class);
    private ThirdPendingManager thirdPendingManager;
    private RegisterManager registerManager;
    private ThirdpartyPendingPullManager thirdpartyPendingPullManager;
    private OrgManager orgManager;
    private MessageOrPendingCacheManager messageOrPendingCacheManager;
    private CustomThirdPendingManager customThirdPendingManager;

    @Override
    public String getIcon() {
        return null;
    }

    @Override
    public String getId() {
        return "thirdPendingSection";
    }

    @Override
    public String getResolveFunction(Map<String, String> preference) {
        return MultiRowVariableColumnTemplete.RESOLVE_FUNCTION;
    }

    @Override
    public String getName(Map<String, String> map) {
        return getSectionName(map);
    }

    @Override
    public String getBaseName(Map<String, String> map) {
        if (map == null) {
            return CIPConstants.SECTION_NAME_PENDING();
        }
        String sectionProviderId = map.get(PropertyName.singleBoardId.name());
        String providerId = StringUtils.removeStart(sectionProviderId, CIPConstants.SECTION_SUFFIX_PENDING);
        if (Strings.isNotBlank(providerId)) {
            if ("999".equals(providerId)) {
                return ResourceUtil.getString("cip.pending.all.pending");
            }
            RegisterPO rp = registerManager.getRegisterByCache(Long.parseLong(providerId));
            if (rp != null) {
                return rp.getLocaleName() + CIPConstants.SUFFIX_PENDING();
            }
        }
        return CIPConstants.SECTION_NAME_PENDING();
    }

    private String getSectionName(Map<String, String> map) {
        String name = (String) map.get("columnsName");
        /*客开修改 2024-12-05 lxy start*/
        try {
            boolean isDwpSystem = customThirdPendingManager.isDwpSystem(map);
            if (isDwpSystem) {
                if (!"DWP Todo".equals(name)) {
                    String columnsName = StrKit.str(FormulaUtil.getVar("columns_name"));
                    name = columnsName;
                }
            }
        } catch (Exception e) {
            log.error("替换自定义栏目名称异常信息:", e);
        }
        
        try {
            boolean isIntegrationSystem = customThirdPendingManager.isIntegrationSystem(map);
            if (isIntegrationSystem) {
                if (!"TIP Todo".equals(name)) {
                    String columnsName = StrKit.str(FormulaUtil.getVar("integration_columns_name"));
                    name = columnsName;
                }
            }
        } catch (Exception e) {
            log.error("替换一体化自定义栏目名称异常信息:", e);
        }
        /*客开修改 2024-12-05 lxy end*/
        if (Strings.isBlank(name)) {
            String sectionProviderId = map.get(PropertyName.singleBoardId.name());
            String providerId = StringUtils.removeStart(sectionProviderId, CIPConstants.SECTION_SUFFIX_PENDING);
            if (StringUtils.isNotBlank(providerId) && !"null".equals(providerId)) {

                if ("999".equals(providerId)) {
                    return ResourceUtil.getString("cip.pending.all.pending");
                }
                RegisterPO rp = registerManager.getRegisterByCache(Long.parseLong(providerId));
                if (rp != null) {
                    return rp.getLocaleName() + CIPConstants.SUFFIX_PENDING();
                }
            }
            return CIPConstants.SECTION_NAME_PENDING();
        }
        return name;
    }

    @Override
    public Integer getTotal(Map<String, String> map) {
        String sectionProviderId = map.get(PropertyName.singleBoardId.name());
        /*客开修改 2024-12-05 lxy start*/
        try {
            boolean isDwpSystem = customThirdPendingManager.isDwpSystem(map);
            if (isDwpSystem) {
                customThirdPendingManager.saveThirdPending();
            }
        } catch (Exception e) {
            log.error("添加dwp系统待办数据到数据库thirdparty_pending表中报错信息:", e);
        }
        try {
            boolean integrationSystem = customThirdPendingManager.isIntegrationSystem(map);
            if (integrationSystem) {
                customThirdPendingManager.saveIntegrationThirdPending();
            }
        } catch (Exception e) {
            log.error("添加一体化系统待办数据到数据库thirdparty_pending表中报错信息:", e);
        }
        /*客开修改 2024-12-05 lxy end*/
        String designatedValue = map.get("designated_value");
        String providerId = StringUtils.removeStart(Strings.isNotBlank(sectionProviderId) ? sectionProviderId : designatedValue, CIPConstants.SECTION_SUFFIX_PENDING);
        Long registerId = NumberUtils.toLong(providerId);
        List<Long> thirdSource = null;
        Long memberId = AppContext.currentUserId();
        String panel = map.get("panel");
        String sourceIds = map.get(CIPConstants.SECTION_PART_SOURCE);
        try {
            thirdSource = processPendingSource(map, registerId);
            Callable<String> call = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    thirdpartyPendingPullManager.transferThirdPending4Section(registerId, memberId, panel, sourceIds, true);
                    return "success";
                }
            };
            Future<String> future = ExecutorServiceFactory.getDefaultThreadPool().submit(call);
            future.get(5, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            log.error("获取待办总数超时5秒，直接查数据库！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return thirdPendingManager.findPendingsCountByRegisterList(thirdSource, memberId);
    }

    @Override
    public BaseSectionTemplete projection(Map<String, String> map) {

        String sectionProviderId = map.get(PropertyName.singleBoardId.name());
        String providerId = StringUtils.removeStart(sectionProviderId, CIPConstants.SECTION_SUFFIX_PENDING);
        MultiRowVariableColumnTemplete c = new MultiRowVariableColumnTemplete();
        User user = AppContext.getCurrentUser();
        long userId = user.getId();
        int count = c.getPageSize(map)[0];
        c.setDataNum(count);
        Long registerId = Long.valueOf(providerId);
        List<Long> thirdSource = null;
        try {
            FlipInfo fi = new FlipInfo();
            fi.setNeedTotal(false);
            fi.setSize(count);
            //不是组合的按原有逻辑，需要先确定是否是组合，组合再按组合取代办，如是全部待办则取全部
            String panel = map.get("panel");
            String sourceIds = map.get(CIPConstants.SECTION_PART_SOURCE);
            thirdSource = processPendingSource(map, registerId);
            thirdpartyPendingPullManager.transferThirdPending4Section(registerId, userId, panel, sourceIds, true);

            List<ThirdPendingPO> ps = thirdPendingManager.findPendingsByRegisterList(thirdSource, userId, fi, false);

            Map<Long, RegisterPO> batchRegisterMap = registerManager.getBatch(thirdSource);
            for (int i = 0; i < count; i++) {
                MultiRowVariableColumnTemplete.Row row = c.addRow();
                if (CollectionUtils.isEmpty(ps)) {
                    continue;
                }
                if (i >= ps.size()) {
                    continue;
                }
                Cell cell = row.addCell();

                ThirdPendingPO p = ps.get(i);
                RegisterPO register = batchRegisterMap.get(p.getRegisterId());
                String senderName = CIPUtil.getPendingSenderName(orgManager, p);
                cell.setAlt(p.getTitle());
                //样式
                cell.setClassName(p.getReadState() != null && p.getReadState().intValue() == 1 ? "" : "ThirdPendingNoRead");
                cell.setCellContent(p.getTitle());
                cell.setLinkURL(CIPUtil.getCipPendigOpenURL(p.getUrl(), String.valueOf(register.getAppCode()), String.valueOf(p.getId()), false));
                Cell createDate = row.addCell();
                createDate.setAlt(Datetimes.formatDate(p.getCreationDate()));
                createDate.setCellContent(Datetimes.formatDate(p.getCreationDate()));

                Cell createName = row.addCell();
                createName.setAlt(senderName);
                createName.setCellContent(senderName);

                /*客开修改 2024-12-05 lxy 屏蔽自定义栏目应用类型、应用名称显示 start */
                try {
                    boolean isDwpSystem = customThirdPendingManager.isDwpSystem(map);
                    if (isDwpSystem) {
//                        Cell classification = row.addCell();
//                        classification.setAlt(Strings.isBlank(p.getClassify()) ? ResourceUtil.getString("common.toolbar.state.pending.label") : p.getClassify());
//                        classification.setCellContent(p.getClassify());
//                        Cell registerNameCell = row.addCell();
//                        String regiserName = register.getLocaleName();
//                        registerNameCell.setAlt(regiserName);
//                        registerNameCell.setCellContent(regiserName);
                    }
                } catch (Exception e) {
                    log.error("屏蔽自定义栏目应用类型、应用名称显示报错信息:", e);
                }
                /*客开修改 2024-12-05 lxy end*/
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        c.setShowBottomButton(true);
        try {
            c.addBottomButton(BaseSectionTemplete.BOTTOM_BUTTON_LABEL_MORE, "/thirdPendingController.do?method=morePending&panel=" + map.get("panel") + "&registerId=" + Strings.join(thirdSource, ",") + "&sectionName=" + java.net.URLEncoder.encode(getSectionName(map), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage(), e);
        }
        return c;
    }

/**
 * 第三方来源组合（门户原因，不能实现，废弃）
 * @deprecated
 * @param map
 * @throws BusinessException
 *
 */
//	private List<Long> getThirdSources(Map<String, String> map) throws BusinessException {
//		List<Long> thirdSource = new ArrayList<Long>();
//		List<MessageOrPending> sections =messageOrPendingCacheManager.getThirdPendingCache4Section();
//		for (MessageOrPending messageOrPending : sections) {
//			String isSource = map.get("third_sources_"+messageOrPending.getRegisterId()+"_name");
//			if(Strings.isNotBlank(isSource)) {
//				thirdSource.add(messageOrPending.getRegisterId());
//			}
//		}
//		return thirdSource;
//	}

    /**
     * 仅移动端待办配置判断限制
     */
    @Override
    public boolean isAllowUsed() {
        return CIPUtil.isPending(true, false);
    }

    @Override
    public boolean isAllowUserUsed(Map<String, String> preference) {
        String sectionProviderId = preference.get(PropertyName.singleBoardId.name());
        String registerID = null;
        if (Strings.isNotBlank(sectionProviderId)) {
            registerID = StringUtils.removeStart(sectionProviderId, CIPConstants.SECTION_SUFFIX_PENDING);
            if ("999".equals(registerID)) {
                return true;
            }
        } else {
            String desigeData = preference.get("designated_value");
            if (Strings.isNotBlank(desigeData)) {
                registerID = StringUtils.removeStart(desigeData, CIPConstants.SECTION_SUFFIX_PENDING);
            }
        }
        if (Strings.isNotBlank(registerID)) {
            RegisterPO register = registerManager.getRegisterByCache(NumberUtils.toLong(registerID));
            if (register != null) {
                try {
                    if (CIPUtil.checkPendingAcl(register, AppContext.currentUserId())) {
                        return CIPUtil.isPending(NumberUtils.toLong(registerID), false);
                    }
                } catch (BusinessException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return false;
    }

    @Override
    public boolean isAllowUserUsed(String singleBoardId) {
        if (Strings.isNotBlank(singleBoardId)) {
            String registers = StringUtils.removeStart(singleBoardId, CIPConstants.SECTION_SUFFIX_PENDING);
            Long regiserId = NumberUtils.toLong(registers);
            if (999L == regiserId.longValue()) {
                return true;
            }
            RegisterPO register = registerManager.getRegisterByCache(regiserId);
            if (register != null) {
                try {
                    if (CIPUtil.checkPendingAcl(register, AppContext.currentUserId())) {
                        return CIPUtil.isPending(regiserId, false);
                    }
                } catch (BusinessException e) {
                    log.error(e.getMessage(), e);
                }
            }

        }
        return false;
    }

    @Override
    public boolean isShowTotal() {
        return true;
    }

    @Override
    public BaseSectionTemplete mProjection(Map<String, String> preference) {
        User user = AppContext.getCurrentUser();
        long userId = user.getId();
        int count = SectionUtils.getSectionCount(3, preference);
        String countNum = preference.get("countNum");
        if (Strings.isNotBlank(countNum)) {
            count = Integer.parseInt(countNum);
        }
        String sectionProviderId = preference.get("designated_value");
        String providerId = StringUtils.removeStart(sectionProviderId, CIPConstants.SECTION_SUFFIX_PENDING);
        FlipInfo fi = new FlipInfo();
        fi.setNeedTotal(false);
        fi.setSize(count);
        Long registerId = Long.valueOf(providerId);
        MListTemplete c = new MListTemplete();
        try {
            String panel = preference.get("panel");
            String sourceIds = preference.get(CIPConstants.SECTION_PART_SOURCE);
            List<Long> thirdSource = processPendingSource(preference, registerId);
            thirdpartyPendingPullManager.transferThirdPending4Section(registerId, userId, panel, sourceIds, false);
            RegisterPO register = registerManager.getRegisterByCache(registerId);
            if (null == register) {
                return c;
            }
            List<ThirdPendingPO> ps = thirdPendingManager.findPendingsByRegisterList(thirdSource, userId, fi, false);

            //列表
            if (CollectionUtils.isNotEmpty(ps)) {
                for (ThirdPendingPO p : ps) {
                    MListTemplete.Row row = c.addRow();
                    row.setSubject(p.getTitle());
                    row.setCreateDate(MListTemplete.showDate(p.getCreationDate()));
                    //移动端传已读未读状态
                    row.setReadFlag(p.getReadState() != null && Strings.equals("1", p.getReadState().toString()) ? "true" : "false");
                    String gotoParams = "";
                    try {
                        gotoParams = M3PendingUtils.getPendingGotoParams(p);
                    } catch (BusinessException e) {
                        log.error(e.getMessage(), e);
                    }
                    row.setLink(gotoParams);
                    String senderName = CIPUtil.getPendingSenderName(orgManager, p);
                    row.setCreateMember(Strings.isNotBlank(senderName) ? senderName : p.getSenderName());
                }
                c.setDataNum(ps.size());
            }

            c.setMoreLink(SystemEnvironment.getContextPath() + "/m3/apps/v5/cip/html/cipThirdPendingList.html?VJoinOpen=VJoin&appCode=" + register.getId());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return c;
    }

    /**
     * 处理组合来源
     *
     * @param map
     * @param registerId
     * @return
     * @throws BusinessException
     */
    private List<Long> processPendingSource(Map<String, String> map, Long registerId) throws BusinessException {
        String panel = map.get("panel");
        String sourceIds = map.get(CIPConstants.SECTION_PART_SOURCE);
        List<Long> thirdSource = new ArrayList<Long>();
        //原有待办
        thirdSource.add(registerId);
        // 全部和超过1的组合
        if (Strings.isNotBlank(sourceIds)) {
            return CIPUtil.newLongArrayList(sourceIds);
        } else if (CIPConstants.SECTION_ALL_SOURCE.equalsIgnoreCase(panel) || 999L == registerId.longValue()) {
            thirdSource = messageOrPendingCacheManager.getThirdPendingRegisterIdListCache(true);
        }
        return thirdSource;
    }

    public void setThirdpartyPendingPullManager(ThirdpartyPendingPullManager thirdpartyPendingPullManager) {
        this.thirdpartyPendingPullManager = thirdpartyPendingPullManager;
    }

    public void setOrgManager(OrgManager orgManager) {
        this.orgManager = orgManager;
    }

    public void setRegisterManager(RegisterManager registerManager) {
        this.registerManager = registerManager;
    }

    public void setThirdPendingManager(ThirdPendingManager thirdPendingManager) {
        this.thirdPendingManager = thirdPendingManager;
    }

    public void setMessageOrPendingCacheManager(MessageOrPendingCacheManager messageOrPendingCacheManager) {
        this.messageOrPendingCacheManager = messageOrPendingCacheManager;
    }

    public void setCustomThirdPendingManager(CustomThirdPendingManager customThirdPendingManager) {
        this.customThirdPendingManager = customThirdPendingManager;
    }

    @Override
    public PortletPackageTemplete resetPreferenceFromImport(Map<String, String> preference) {
        PortletPackageTemplete portletPackageTemplete = new PortletPackageTemplete();
        List<String> message = new ArrayList<>();
        String sectionProviderId = preference.get("designated_value");
        //获取 thirdparty_register 中的id 和 thirdparty_msg_pending_cfg REGISTER_ID
        String providerId = StringUtils.removeStart(sectionProviderId, CIPConstants.SECTION_SUFFIX_PENDING);
        //匹配数据库，如果匹配上，不做操作，直接返回，如果匹配不上，提示信息：xxx 无数据，请您重新设置。
        if (providerId != null) {
            RegisterPO register = registerManager.getRegisterByCache(Long.valueOf(providerId));
            if (register == null) {
                String columnsName = preference.get("columnsName");
                message.add(columnsName + "无数据，请您重新设置。");
                portletPackageTemplete.setMessages(message);
            }
        }
        portletPackageTemplete.setPreference(preference);
        return portletPackageTemplete;
    }

    @Override
    public Map<String, String> resetPreferenceFromExport(Map<String, String> preference) {
        return super.resetPreferenceFromExport(preference);
    }

}
